package com.softer.chengxin.file.service.impl;

import com.softer.chengxin.common.domin.Common;
import com.softer.chengxin.common.domin.CommonResult;
import com.softer.chengxin.common.enums.ResultEnum;
import com.softer.chengxin.common.util.GetFileNameUtil;
import com.softer.chengxin.file.controller.FileController;
import com.softer.chengxin.file.dao.FileDao;
import com.softer.chengxin.file.entity.FileDTO;
import com.softer.chengxin.file.entity.FileVO;
import com.softer.chengxin.file.service.FileService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Gong Zhiyang
 * @date 2018/10/10
 */
@Service
public class FileServiceImpl implements FileService {
    private Logger logger = LoggerFactory.getLogger(FileController.class);
    private static final String OBLIQUE = "/";
    private static final String PROJECT = "project";
    private static final String PERSON = "person";
    private static final String INFO = "info";
    private static final String CORP = "corp";

    @Autowired
    private FileDao fileDao;

    /**
     * 上传文件
     *
     * @param file    文件流
     * @param fileDTO 查询实体
     * @param id      企业ID
     * @return 结果
     */
    @Override
    public CommonResult upload(MultipartFile file, FileDTO fileDTO, Integer id) {
        FileVO fileVO = new FileVO();
        try {
            //文件大小
            long size = file.getSize();
            fileVO.setFileSize(size / 1024);
            fileVO.setCorId(id);
            //服务器路径没有bin,linux下是"/",windows下是"\"
            String imgPath = "./picture";
            String path = imgPath;
            //文件名
            String filename = file.getOriginalFilename();
            if (StringUtils.isBlank(filename)) {
                return new CommonResult(ResultEnum.FAIL.getCode(), "上传图片不存在");
            }
            //获取后缀
            String suffix = filename.substring(filename.lastIndexOf("."));
            if (!suffix.toLowerCase().contains("jpg")) {
                return new CommonResult(ResultEnum.FAIL.getCode(), "只能上传JPG格式");
            }
            fileVO.setFileType(suffix);
            fileVO.setFileName(filename);
            String newName = GetFileNameUtil.creatName() + suffix;
            fileVO.setNewFilName(newName);
            fileVO.setPersonId(Common.ZERO);
            fileVO.setProjectId(Common.ZERO);
            fileVO.setInfoId(Common.ZERO);
            StringBuilder pathBuilder = new StringBuilder(2);
            if (StringUtils.isNotBlank(fileDTO.getPersonId())) {
                fileVO.setPersonId(fileDTO.getPersonId());
                pathBuilder.append(OBLIQUE).append(PERSON);
                imgPath += pathBuilder;
                pathBuilder.append(OBLIQUE).append(newName);
                path += pathBuilder;
            } else if (StringUtils.isNotBlank(fileDTO.getProjectId())) {
                fileVO.setProjectId(fileDTO.getProjectId());
                pathBuilder.append(OBLIQUE).append(PROJECT);
                imgPath += pathBuilder;
                pathBuilder.append(OBLIQUE).append(newName);
                path += pathBuilder;
            } else if (StringUtils.isNotBlank(fileDTO.getInfoId())) {
                fileVO.setInfoId(fileDTO.getInfoId());
                pathBuilder.append(OBLIQUE).append(INFO);
                imgPath += pathBuilder;
                pathBuilder.append(OBLIQUE).append(newName);
                path += pathBuilder;
            } else {
                pathBuilder.append(OBLIQUE).append(CORP);
                imgPath += pathBuilder;
                pathBuilder.append(OBLIQUE).append(newName);
                path += pathBuilder;
            }
            fileVO.setType(fileDTO.getType());
            fileVO.setPath(path);
            uploadFileUtil(file, imgPath, newName);
            //增加数据库一条记录
            int num = fileDao.add(fileVO);
            if (num > Integer.parseInt(Common.ZERO)) {
                return new CommonResult(ResultEnum.SUCCESS.getCode(), path, fileVO.getId(), filename);
            }
        } catch (Exception e) {
            logger.error("上传文件错误", e);
        }
        return new CommonResult(ResultEnum.FAIL.getCode(), "上传失败");
    }

    /**
     * 通过文件类型查询文件
     *
     * @param fileDTO 查询实体
     * @param id      企业ID
     * @return 文件信息
     */
    @Override
    public List<FileVO> getFileList(FileDTO fileDTO, Integer id) {
        return fileDao.getFileList(fileDTO, id);
    }

    /**
     * 删除附件
     *
     * @param id 附件ID
     * @return 删除结果
     */
    @Override
    public CommonResult delete(Integer id) {
        int num = fileDao.delete(id);
        return CommonResult.response(num);
    }

    /**
     * 获取图片路径
     *
     * @param fileDTO 查询实体
     * @param id      企业ID
     * @param path    路径
     * @return 图片集合
     */
    @Override
    public List<String> getPath(FileDTO fileDTO, Integer id, String path) {
        List<String> list = fileDao.getPath(fileDTO, id);
        List<String> result = new ArrayList<>();
        for (String url : list) {
            url = path + url.substring(1);
            result.add(url);
        }
        return result;
    }

    /**
     * 上传文件的方法
     *
     * @param file：文件的字节
     * @param imgPath：文件的路径
     * @param imgName：文件的名字
     * @throws Exception
     */
    public void uploadFileUtil(MultipartFile file, String imgPath, String imgName) throws Exception {
        FileOutputStream out = null;
        try {
            File targetFile = new File(imgPath);
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }
            out = new FileOutputStream(imgPath + "/" + imgName);
            byte[] bytes = compressPic(file.getBytes(), 0.1f);
            out.write(bytes);
            out.flush();
        } finally {
            try {
                InputStream in = file.getInputStream();
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 等分辨率压缩
     *
     * @param imageByte
     * @param quality
     * @return
     */
    public static byte[] compressPic(byte[] imageByte, float quality) {
        byte[] inByte = null;
        try {
            ByteArrayInputStream byteInput = new ByteArrayInputStream(imageByte);
            Image img = ImageIO.read(byteInput);
            float newWidth = img.getWidth(null);
            float newHeight = img.getHeight(null);
            Image image = img.getScaledInstance((int) newWidth, (int) newHeight, Image.SCALE_SMOOTH);
            // 缩放图像
            BufferedImage tag = new BufferedImage((int) newWidth,
                    (int) newHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = tag.createGraphics();
            // 绘制缩小后的图
            g.drawImage(image, 0, 0, null);
            g.dispose();
            ByteArrayOutputStream out = new ByteArrayOutputStream(imageByte.length);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);
            /* 压缩质量 */
            jep.setQuality(quality, true);
            encoder.encode(tag, jep);
            inByte = out.toByteArray();
            out.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return inByte;
    }
}
